import time
import psutil
import subprocess
import json
import os
import winreg
import sys
import threading

def get_exe_name(path):
    if path.find('"') != -1:
        path = path.replace('"', '')
    path = path.replace('\\', '/')
    return path.split('/')[-1]

def load_config():
    if getattr(sys, 'frozen', False):
        # 如果是打包后的 exe 文件
        program_dir = os.path.dirname(sys.executable)
    else:
        # 如果是运行 Python 脚本
        program_dir = os.path.dirname(os.path.abspath(__file__))
    config_path = os.path.join(program_dir, 'config.json')
    if os.path.exists(config_path):
        try:
            with open(config_path, 'r', encoding='utf-8') as f:
                config = json.load(f)
                if isinstance(config.get("processes"), list):
                    return config
                else:
                    print("Invalid processes format in config file, expected a list")
                    return {"processes": []}
        except json.JSONDecodeError as e:
            print(f"Invalid JSON format in config file: {str(e)}")
            return {"processes": []}
    else:
        return {"processes": []}

def save_config(config):
    if getattr(sys, 'frozen', False):
        # 如果是打包后的 exe 文件
        program_dir = os.path.dirname(sys.executable)
    else:
        # 如果是运行 Python 脚本
        program_dir = os.path.dirname(os.path.abspath(__file__))
    config_path = os.path.join(program_dir, 'config.json')
    try:
        with open(config_path, 'w', encoding='utf-8') as f:
            json.dump(config, f, indent=4)
    except Exception as e:
        print(f"保存配置文件失败: {str(e)}")

def start_pid_alive():
    config = load_config()
    process_list = config.get("processes", [])
    
    for process in process_list:
        path = process.get("path", "")
        config_path = process.get("config", "")
        exe_name = get_exe_name(path)
        
        process_running = False
        for proc in psutil.process_iter():
            try:
                if proc.name() == exe_name:
                    process_running = True
                    break
            except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
                continue

        if not process_running:
            try:
                args = [path]
                if config_path:
                    if not os.path.isabs(config_path):
                        config_path = os.path.join(os.path.dirname(path), config_path)
                    args.extend(["--config", config_path])
                subprocess.Popen(args, cwd=os.path.dirname(path))
                print(f"Process {exe_name} started with args: {args[1:]}")
            except Exception as e:
                print(f"Failed to start process {path}: {str(e)}")
        else:
            print(f"Process {exe_name} is already running.")

def monitor_processes():
    while True:
        start_pid_alive()
        time.sleep(10)

def set_startup():
    try:
        key = winreg.OpenKey(winreg.HKEY_CURRENT_USER,
                             r"Software\Microsoft\Windows\CurrentVersion\Run",
                             0, winreg.KEY_SET_VALUE)
        exe_path = os.path.abspath(__file__)
        winreg.SetValueEx(key, "ProcessGuardNoUI", 0, winreg.REG_SZ, exe_path)
        winreg.CloseKey(key)
        print("已设置开机自启")
    except Exception as e:
        print(f"设置开机自启失败: {str(e)}")

def remove_startup():
    try:
        key = winreg.OpenKey(winreg.HKEY_CURRENT_USER,
                             r"Software\Microsoft\Windows\CurrentVersion\Run",
                             0, winreg.KEY_ALL_ACCESS)
        winreg.DeleteValue(key, "ProcessGuardNoUI")
        winreg.CloseKey(key)
        print("已移除开机自启")
    except Exception as e:
        print(f"移除开机自启失败: {str(e)}")

if __name__ == "__main__":
    if len(sys.argv) > 1:
        if sys.argv[1] == "set_startup":
            set_startup()
        elif sys.argv[1] == "remove_startup":
            remove_startup()

    # 启动进程监控线程
    monitor_thread = threading.Thread(target=monitor_processes, daemon=True)
    monitor_thread.start()

    try:
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        print("程序已退出")
